home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Windows Expert
/
Windows Expert.iso
/
others
/
instal.zip
/
WSLIB
/
COPY.C
next >
Wrap
C/C++ Source or Header
|
1991-06-12
|
30KB
|
1,121 lines
/*
* copy.c - Copy routine for wInstall
*
* notes:
* we now use the LZCopy stuff so COMPRESS is NOT defined
* we now set the crit error handler ourselves so CHECKFLOPPY is
* NOT defined
*/
#include <dos.h>
#include <string.h>
#include "lobotomy.h"
// ...and lets even remove some more brain cells...
#define NOWINSTYLES //- WS_*, CS_*, ES_*, LBS_*, SBS_*, CBS_*
#define NOSHOWWINDOW //- SW_*
#define NOATOM //- Atom Manager routines
#define NOCOLOR //- Screen colors
#define NOGDI //- All GDI defines and routines
#define NOMINMAX //- Macros min(a,b) and max(a,b)
#define NOOPENFILE //- OpenFile(), OemToAnsi, AnsiToOem, and OF_*
#define NOTEXTMETRIC //- typedef TEXTMETRIC and associated routines
#define NOWINOFFSETS //- GWL_*, GCL_*, associated routines
#include <windows.h>
#include "sulib.h"
#include "..\install.h"
#include "ws.h"
#include "progdde.h"
#include "gauge.h"
char szDisks[] = "disks";
BOOL NEAR GetDiskPath(char cDisk, PSTR szPath);
WORD FAR PASCAL wsCopyStatus(int msg, int n, LPSTR szFile);
BOOL fnMystrstr(char *szSrcStr, char *szSearchStr);
/*
* global vars used by DosCopy
*/
static LPSTR lpBuf = NULL; // copy buffer
static int iBuf = 0; // usage count
static WORD nBufSize;
static char cDisk;
static LPSTR szEdit;
extern PSTR pErrMsg;
#define MAXBUF (60 * 1024) // size of default copy buffer
void NEAR PASCAL AllocCopyBuf();
void NEAR PASCAL FreeCopyBuf();
void FAR PASCAL fartonear(LPSTR dst, LPSTR src)
{
while (*src)
*dst++ = *src++;
*dst = 0;
}
/* WORD FileCopy (szSource, szDir, fpfnCopy, WORD f)
*
* This function will copy a group of files to a single destination
*
* ENTRY:
*
* szSourc : pointer to a SETUP.INF section
* szDest : pointer to a string containing the target DIR
* fpfnCopy : callback function used to notify called of copy status
* fCopy : flags
*
* FC_SECTION - szSource is a section name
* FC_LIST - szSource is a pointer to a list, each item \0
* terminated and the whole list \0\0 terminated
* FC_FILE - szSource is a file name.
* FC_QUALIFIED - szSource is a fully qualified file name.
* FC_DEST_QUALIFIED - szDir is fully qualified. Don't expand this.
*
* NOTES:
* if szSource points to a string of the form '#name' the section
* named by 'name' will be used as the source files
*
* the first field of each line in the secion is used as the name of the
* source file. A file name has the following form:
*
* #:name
*
* # - Disk number containing file 1-9,A-Z
* name - name of the file, may be a wild card expression
*
* Format for copy status function
*
* BOOL FAR PASCAL CopyStatus(int msg, int n, PSTR szFile)
*
* msg:
* COPY_ERROR error occured while copying file(s)
* n is the DOS error number
* szFile is the file that got the error
* return: TRUE ok, FALSE abort copy
*
* COPY_STATUS Called each time a new file is copied
* n is the percent done
* szFile is the file being copied
* return: TRUE ok, FALSE abort copy
*
* COPY_INSERTDISK Please tell the user to insert a disk
* n is the disk needed ('1' - '9')
* return: TRUE try again, FALSE abort copy
*
* COPY_QUERYCOPY Should this file be copied?
* n line index in SETUP.INF section (0 based)
* szFile is the line from section
* return: TRUE copy it, FALSE dont copy
*
* COPY_START Sent before any files are copied
*
* COPY_END Sent after all files have been copied
* n is dos error if copy failed
*
*
* EXIT: returns TRUE if successful, FALSE if failure.
*
*/
WORD FAR PASCAL FileCopy (LPSTR szSource, PSTR szDir, FPFNCOPY fpfnCopy, WORD fCopy)
{
int err = ERROR_OK;
char szFile[MAXPATHLEN];
char szPath[MAXPATHLEN];
char szLogSrc[MAXPATHLEN];
char szSrcBase[15];
char szSrc[MAXPATHLEN];
char szErrFile[MAXPATHLEN];
LPSTR far *pFileList;
LPSTR far *pFileListBegin;
LPSTR pFile;
LPSTR pFileBegin;
BOOL f;
BOOL fDoCopy;
int n = 0;
int nDisk;
char cDisk;
int cntFiles = 0;
PINF pinf;
#define CALLBACK(msg,n,pFile) \
(fpfnCopy ? ((*fpfnCopy)((WORD)(msg),(int)(n),(LPSTR)(pFile))) : FC_IGNORE)
if (!szSource || !*szSource || !szDir || !*szDir)
return FALSE;
#ifndef COMPRESS
AllocCopyBuf();
#endif
/*
* fix up the drive in the destination
*/
if ( fCopy & FC_DEST_QUALIFIED )
lstrcpy(szPath,szDir);
else
ExpandFileName(szDir,szPath);
fCopy &= ~FC_DEST_QUALIFIED;
if (szSource[0] == '#' && fCopy == FC_FILE)
{
fCopy = FC_SECTION;
++szSource;
}
switch (fCopy)
{
case FC_LSTPTR:
pFileList = pFileListBegin = (LPSTR far *)szSource;
pFileBegin = *pFileList;
while ( pFileList[n] ) {
if ( *pFileList[n] )
++cntFiles;
++n;
}
break;
case FC_SECTION:
{
char buf[40];
fartonear(buf, szSource);
szSource = infFindSection(NULL,buf);
if (szSource == NULL)
goto exit;
fCopy = FC_LIST;
}
// fall through to FC_LIST
case FC_LIST:
pFileBegin = szSource;
cntFiles = infLineCount(szSource);
break;
case FC_FILE:
case FC_QUALIFIED:
default:
pFileBegin = szSource;
cntFiles = 1;
}
/*
* Does the destination directory exist? if not create it.
*/
if (!DosValidDir(szPath)) {
err = DosMkDir(szPath);
// oh no! this is bad
if (err != ERROR_OK) {
CALLBACK(COPY_ERROR,err,szPath);
goto exit;
}
}
/*
* walk all files in the list and call DosCopy ....
*
* NOTES:
* we must walk file list sorted by disk number.
* we should use the disk that is currently inserted.
* we should do a find first/find next on the files????
* we need to check for errors.
* we need to ask the user to insert disk in drive.
*
*/
CALLBACK(COPY_START,0,NULL);
for (nDisk = 1; cntFiles > 0; nDisk++) {
cDisk = CHDISK(nDisk);
pFileList = pFileListBegin;
pFile = pFileBegin;
n = 0;
while (pFile) {
/*
* should we copy this file?
* copy the files in disk order.
*/
fDoCopy = pFile[1] == ':' && cDisk == UP_CASE(pFile[0]) ||
pFile[1] != ':' && nDisk == 1 && *pFile ||
fCopy == FC_QUALIFIED;
if (fDoCopy)
cntFiles--; // done with a file. decrement count.
if (fDoCopy && CALLBACK(COPY_QUERYCOPY,n,pFile)) {
if (CALLBACK(COPY_STATUS, 0, pFile) == FC_ABORT) {
err = ERROR_NOFILES;
goto exit;
}
// now we convert logical dest into a physical (unless FC_QUALIFIED)
infParseField(pFile, 1, szLogSrc); // logical source
if ( fCopy != FC_QUALIFIED )
ExpandFileName(szLogSrc, szSrc); // full physical source
else
lstrcpy(szSrc,szLogSrc);
tryagain:
// Call low level copy command
err = DosCopy(szSrc, szPath);
if (err != ERROR_OK) {
lstrcpy(szSrcBase, FileName(szSrc)); // save base name
if (err == ERROR_FILENOTFOUND || err == ERROR_PATHNOTFOUND) {
// isolate the path
StripPathName(szSrc);
// now try to get a new path in szSrc
switch (CALLBACK(COPY_INSERTDISK, szLogSrc[0], szSrc)) {
case FC_RETRY:
catpath(szSrc, szSrcBase); // add the file back on
goto tryagain; // and try again...
case FC_ABORT:
goto exit;
case FC_IGNORE:
break;
}
}
// ERROR situation
//
// this may be a real error or something like
// a share violation on a network.
ExpandFileName(szLogSrc, szSrc); // full physical source
// if it is a write error report the destination file
// otherwise report with the source file
switch (err) {
case ERROR_WRITE:
lstrcpy(szErrFile, szPath);
catpath(szErrFile, szSrcBase);
break;
default:
lstrcpy(szErrFile, szSrc);
}
switch (CALLBACK(COPY_ERROR, err, szErrFile)) {
case FC_RETRY:
goto tryagain;
case FC_ABORT:
goto exit;
case FC_IGNORE:
break;
}
}
if (CALLBACK(COPY_STATUS,100,pFile) == FC_ABORT) {
err = !ERROR_OK;
goto exit;
}
}
/*
* Move on to next file in the list
*/
n++;
if (fCopy == FC_LSTPTR)
pFile = *(++pFileList);
else if (fCopy == FC_LIST)
pFile = infNextLine(pFile);
else
pFile = NULL;
}
}
err = ERROR_OK;
exit:
CALLBACK(COPY_END,err,NULL);
#ifndef COMPRESS
FreeCopyBuf();
#endif
return err;
#undef CALLBACK
}
#ifndef COMPRESS
/* AllocCopyBuf()
*
* allocate a buffer for DosCopy to use
*
*/
void NEAR PASCAL AllocCopyBuf()
{
if (iBuf++ == 0)
{
nBufSize = MAXBUF;
for(;;)
{
lpBuf = FALLOC(nBufSize);
if (lpBuf || nBufSize == 1)
break;
nBufSize /= 2;
}
if (lpBuf == NULL)
iBuf--;
}
}
/* FreeCopyBuf()
*
* free copy buffer, if its use count is zero
*
*/
void NEAR PASCAL FreeCopyBuf()
{
if (iBuf > 0 && --iBuf == 0 && lpBuf)
{
FFREE(lpBuf);
}
}
#endif
PSTR GetExtension(PSTR szFile)
{
PSTR ptr;
for (ptr = szFile; *ptr && *ptr != '.'; ptr++);
if (*ptr != '.')
return NULL;
else
return ptr+1;
}
BOOL GetCompressedName(PSTR szComp, PSTR szSrc)
{
PSTR ptr;
lstrcpy(szComp, szSrc);
ptr = GetExtension(szComp);
if (ptr && !lstrcmpi(ptr, "sys")) {
szComp[lstrlen(szComp)-1] = '$';
return TRUE;
}
return FALSE;
}
/* DosCopy(PSTR szSrc, PSTR szPath)
*
* Copy the file specifed by szSrc to the drive and directory
* specifed by szPath
*
* ENTRY:
* szSrc - File name to copy from
* szPath - directory to copy to
*
* RETURNS:
* 0 - no error, else dos error code
*
*/
int NEAR DosCopy(PSTR szSrc, PSTR szPath)
{
FCB fcb;
WORD size;
int fhSrc,fhDst;
char szFile[MAXPATHLEN];
char szComp[MAXPATHLEN];
int f = ERROR_OK;
unsigned date;
unsigned time;
long l;
BOOL bCompressedName;
#ifdef DEBUG
if (fDontCopy)
return ERROR_OK;
if (infGetProfileString(NULL,"setup","copy",szFile) && szFile[0] == 'f')
return ERROR_OK;
#endif
AllocCopyBuf();
if (!lpBuf)
return ERROR_NOMEMORY;
#ifdef CHECK_FLOPPY
if (!IsDiskInDrive(szSrc[0]))
{
f = ERROR_FILENOTFOUND;
goto errfree;
}
#endif
// allows both sy$ and sys on the disks
if (GetCompressedName(szComp, szSrc) &&
DosFindFirst(&fcb, szComp, ATTR_FILES)) {
bCompressedName = TRUE;
} else {
bCompressedName = FALSE;
if (!DosFindFirst(&fcb, szSrc, ATTR_FILES)) {
f = ERROR_FILENOTFOUND;
goto errfree;
}
}
/*
* copy every file that matches the file pattern passed in.
*/
do
{
/*
* create the source file name from the source path and the file
* name that DosFindFirst/Next found
*/
lstrcpy(szFile,szSrc);
StripPathName(szFile);
catpath(szFile,fcb.szName);
fhSrc = FOPEN(szFile);
if (fhSrc == -1)
{
f = FERROR();
goto errfree;
}
/* Save date of opened file */
if (_dos_getftime(fhSrc,&date,&time))
goto errclose1;
/*
* create the destination file name from the dest path and the file
* name that DosFindFirst/Next found
*/
lstrcpy(szFile,szPath);
// don't support wildcards for compressed files
if (bCompressedName)
catpath(szFile,FileName(szSrc));
else
catpath(szFile,fcb.szName); // used name from fcb
fhDst = FCREATE(szFile);
if (fhDst == -1)
{
f = FERROR();
goto errclose1;
}
while (size = FREAD(fhSrc,lpBuf,nBufSize))
{
if (FWRITE(fhDst,lpBuf,size) != size)
{
/* write error? */
f = FERROR();
if (f == ERROR_OK)
f = ERROR_WRITE;
goto errclose;
}
}
/* Restore date of written file */
_dos_setftime(fhDst,date,time);
errclose:
FCLOSE(fhDst);
errclose1:
FCLOSE(fhSrc);
} while (f == ERROR_OK && DosFindNext(&fcb));
errfree:
FreeCopyBuf();
return f;
}
/* BOOL fnMystrstr(char *szSrcStr, char *szSearchStr);
*
* Function will return BOOL value as to weather the Search string exists
* any where within the source string. The difference between this func
* the C run time func is that this one is simpler and is also not case
* sensitive.
*
* ENTRY: szSrcStr - Char buffer to be searched.
*
* szSearchStr - String that will be searched for.
*
* EXIT: BOOL value as to weather or not string was found.
*
*
* WARNING: Source and search strings MUST be null terminated.
*
*
*/
BOOL fnMystrstr(szSrcStr, szSearchStr)
char *szSrcStr;
char *szSearchStr;
{
unsigned len; // Get length of search string.
while (szSearchStr[0] == '.' && SLASH(szSearchStr[1]))
szSearchStr+=2;
len = lstrlen(szSearchStr);
while ( !ISEOL(*szSrcStr) ) {
if ( ! strnicmp(szSrcStr,szSearchStr,len))
return TRUE;
++szSrcStr;
}
return FALSE;
}
/* BOOL GetDiskPath(char cDisk, szPath)
*
* This function will retrive the full path name for a logical disk
* the code reads the [disks] section of SETUP.INF and looks for
* n = path where n is the disk char. NOTE the disk '0' defaults to
* the root windows directory.
*
* ENTRY:
*
* cDisk : what disk to find 0-9,A-Z
* szPath : buffer to hold disk path
*
*/
BOOL NEAR GetDiskPath(char cDisk, PSTR szPath)
{
char ach[2];
char szBuf[MAXPATHLEN];
if (cDisk == '0')
{
/*
* return the windows setup directory
*/
lstrcpy(szPath,szSetupPath);
return TRUE;
}
/*
* now look in the [disks] section for a full path name
*/
ach[0] = cDisk;
ach[1] = 0;
if ( !infGetProfileString(NULL,szDisks,ach,szPath) )
return FALSE;
infParseField(szPath,1,szPath);
/*
* is the path relative? is so prepend the szDiskPath
*/
if (szPath[0] == '.' || szPath[0] == 0)
{
lstrcpy(szBuf,szDiskPath);
if (! fnMystrstr(szDiskPath,szPath) )
catpath(szBuf,szPath);
lstrcpy(szPath,szBuf);
}
return TRUE;
}
/* BOOL FAR PASCAL ExpandFileName(PSTR szFile, PSTR szPath)
*
* This function will retrive the full path name for a file
* it will expand, logical disk letters to pyshical ones
* will use current disk and directory if non specifed.
*
* if the drive specifed is 0-9, it will expand the drive into a
* full pathname using GetDiskPath()
*
* IE 0:system ==> c:windows\system
* 1:foo.txt a:\foo.txt
*
* ENTRY:
*
* szFile : File name to expandwhat disk to find
* szPath : buffer to hold full file name
*
*/
BOOL FAR PASCAL ExpandFileName(PSTR szFile, PSTR szPath)
{
char szBuf[MAXPATHLEN*2];
if (szFile[1] == ':' && GetDiskPath(szFile[0],szBuf))
{
lstrcpy(szPath,szBuf);
if (szFile[2])
catpath(szPath,szFile + 2);
}
else
{
lstrcpy(szPath,szFile);
}
return TRUE;
}
/*----------------------------------------------------------------------------*\
| wsCopy() |
| |
\*----------------------------------------------------------------------------*/
BOOL PUBLIC wsCopy(PSTR szSection)
{
PINF pinf;
char szSource[MAXSTR];
char szDest[MAXSTR];
char szLocalTmp[MAXSTR];
int nFiles;
int err = ERROR_OK;
char buf[MAXSTR];
// we use different sections for net and win386 setup. net setup
// overrides win386.
dprintf("wsCopy %s\n",szSection);
pinf = infFindSection(NULL,szSection);
if (pinf == NULL)
return FALSE;
ProPrintf(ID_STATUS1, wsLoadSz(IDS_WAITCOPY,NULL));
for (nFiles=0; pinf; pinf = infNextLine(pinf))
{
dprintf("inf line:%ls\n", (LPSTR)pinf);
infParseField(pinf,1,szSource);
if (szSource[0] == '#') {
// count these, and copy below
nFiles += infLineCount(infFindSection(NULL, szSource + 1));
dprintf("nFiles:%d\n", nFiles);
} else
nFiles++;
}
dprintf("nFiles:%d\n", nFiles);
ProSetBarRange(nFiles);
for (pinf = infFindSection(NULL,szSection); pinf; pinf = infNextLine(pinf))
{
infParseField(pinf,1,szSource);
infParseField(pinf,2,szDest);
if ((err = FileCopy(szSource,szDest,(FPFNCOPY)wsCopyStatus,FC_FILE)) != ERROR_OK)
break;
}
return err == ERROR_OK;
}
/*----------------------------------------------------------------------------*\
| define the call back function used by the FileCopy() function. |
| |
\*----------------------------------------------------------------------------*/
WORD FAR PASCAL wsCopyStatus(int msg, int n, LPSTR szFile)
{
char buf[80];
switch (msg)
{
case COPY_INSERTDISK:
return wsInsertDisk(n,szFile);
case COPY_ERROR:
return wsCopyError(n,szFile);
case COPY_QUERYCOPY:
// special case hack for .386 files built into win386.exe
infParseField(szFile, 1, buf);
if (*FileName(buf) == '*')
return FALSE; // don't copy
return TRUE;
case COPY_END:
case COPY_START:
SetErrorMode(msg == COPY_START); // don't crit error on us
break;
case COPY_STATUS:
if (n == 0)
{
dprintf("%ls\n", (LPSTR)szFile);
// if their is a title update it. this allows shared titles
if (infParseField(szFile,2,buf))
ProPrintf(ID_STATUS2, wsLoadSz(IDS_COPYING,NULL), (LPSTR)buf);
}
if (n == 100)
{
ProDeltaPos(1);
}
if (! wsYield() )
return FC_ABORT;
break;
}
return FC_IGNORE;
}
/*----------------------------------------------------------------------------*\
| |
| wsCopyError() |
| |
| Handles errors, as the result of copying files. |
| |
| this may include net contention errors, in witch case the user must |
| retry the operation. |
| |
\*----------------------------------------------------------------------------*/
WORD PUBLIC wsCopyError(int n, LPSTR sz)
{
char buf[200];
char file[MAXSTR];
int res;
lstrcpy(file, sz); // in case our DS moves durring wsLoadSz()
if (!wsLoadSz(IDS_ERROR + n, buf)) {
// error string doesn't exist. if it is a net error use
// net string, if not that use generic error string
if (n > ERROR_SHARE)
wsLoadSz(IDS_ERROR + ERROR_SHARE, buf);
else
wsprintf(buf, wsLoadSz(IDS_ERROR,NULL), n);
}
lstrcat(buf,"\n");
// check for the out of disk space case
if (n == ERROR_WRITE) { // check for out of disk space
dprintf("free space on disk %ld\n", DosDiskFreeSpace(0));
if (DosDiskFreeSpace(0) < 50000)
lstrcat(buf, wsLoadSz(IDS_OUTOFDISK, NULL));
}
lstrcat(buf, file); // add the file name
// pass these through globals
pErrMsg = buf;
res = fDialog(DLG_COPYERROR, GetActiveWindow(), wsErrorDlg);
return res;
}
/*----------------------------------------------------------------------------*\
| |
| wsInsertDisk() |
| |
| Handles errors, as the result of copying files. |
| |
\*----------------------------------------------------------------------------*/
WORD PUBLIC wsInsertDisk(int n, LPSTR szSrcPath)
{
cDisk = (char)n;
szEdit = szSrcPath;
return (WORD)fDialog(DLG_INSERTDISK, GetActiveWindow(), wsDiskDlg);
}
/*----------------------------------------------------------------------------*\
| wsDiskDlg( hDlg, uiMessage, wParam, lParam ) |
| |
| Arguments: |
| hDlg window handle of about dialog window |
| uiMessage message number |
| wParam message-dependent |
| lParam message-dependent |
| |
| Returns: |
| TRUE if message has been processed, else FALSE |
| |
\*----------------------------------------------------------------------------*/
BOOL FAR PASCAL wsDiskDlg(HWND hDlg, unsigned uiMessage, WORD wParam, long lParam)
{
switch (uiMessage)
{
case WM_COMMAND:
switch (wParam)
{
case ID_OK:
// szEdit points to the path that will be retried
GetDlgItemText(hDlg, ID_EDIT, szEdit, MAXSTR);
lstrcpy(szDiskPath, szEdit); // and make this the default
EndDialog(hDlg, FC_RETRY);
break;
case ID_CANCEL:
EndDialog(hDlg, FC_IGNORE);
break;
}
return TRUE;
case WM_INITDIALOG:
{
/*
* now look in the [disks] section for the disk name
* the disk name is the second field.
*/
char ach[2];
char buf[MAXSTR];
char buf2[MAXSTR];
ach[0] = cDisk;
ach[1] = 0;
infGetProfileString(NULL,wsLoadSz(IDS_DISKS,NULL),ach,buf);
infParseField(buf,2,buf2);
SetDlgItemText(hDlg,ID_TEXT,buf2);
SetDlgItemText(hDlg,ID_EDIT,szEdit);
wsDlgInit(hDlg);
MessageBeep(0);
return TRUE;
}
}
return FALSE;
}
/*----------------------------------------------------------------------------*\
| wsYield() |
| |
| Description: |
| Handle any messages in our Que, return when the Que is empty |
| |
| Returns: |
| FALSE if a WM_QUIT message was encountered, TRUE otherwise |
| |
\*----------------------------------------------------------------------------*/
BOOL PUBLIC wsYield()
{
MSG msg;
BOOL retval = TRUE;
while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
if ( msg.message == WM_QUIT )
retval = FALSE;
if (CheckSpecialKeys(&msg))
continue;
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return retval;
}
/***************************************************************************
* BOOL PUBLIC CheckSpecialKeys(PMSG pmsg)
*
* returns:
* TRUE it was special and I delt with it
* FALSE it wasn't special so pass it on
*
**************************************************************************/
BOOL PUBLIC CheckSpecialKeys(LPMSG lpmsg)
{
static HWND hwndOldActive = NULL;
if (lpmsg->message != WM_KEYDOWN)
return FALSE;
switch(lpmsg->wParam) {
// exit keys
case VK_F3:
PostMessage(hwndWS,WM_COMMAND,ID_EXITSETUP,0L);
break;
default:
return FALSE;
}
return TRUE; // yes, this was a special key
}
#define CBSECTORSIZE 512
#define INT13_READ 2
/*--------------------------------------------------------------------------
IsValidDiskette() -
--------------------------------------------------------------------------*/
BOOL NEAR IsValidDiskette(int iDrive)
{
char buf[CBSECTORSIZE];
iDrive |= 0x0020; // make lower case
iDrive -= 'a'; // A = 0, B = 1, etc. for BIOS stuff
return MyReadWriteSector(buf, INT13_READ, iDrive, 0, 0, 1);
}
#ifdef CHECK_FLOPPY
/* BOOL IsDiskInDrive(char cDisk)
*
* Is the specifed disk in the drive
*
* ENTRY:
*
* cDisk : what disk required to be in the drive (logical)
*
* return TRUE if the specifed disk is in the drive
* FALSE if the wrong disk is in the drive or disk error
*
*/
BOOL NEAR IsDiskInDrive(int iDisk)
{
if ((iDisk >= 'A' && iDisk <= 'Z') ||
(iDisk >= 'a' && iDisk <= 'z')) {
if (DosRemoveable(iDisk)) {
if (!IsValidDiskette(iDisk))
return FALSE;
}
return TRUE;
}
return TRUE; // for non drive letters assume a path
// and thus always in.
}
#endif
void FAR PASCAL catpath(PSTR path, PSTR sz)
{
//
// Remove any drive letters from the directory to append
//
if ( sz[1] == ':' )
sz+=2;
//
// Remove any current directories ".\" from directory to append
//
while (sz[0] == '.' && SLASH(sz[1]))
sz+=2;
//
// Dont append a NULL string or a single "."
//
if (*sz && !(sz[0] == '.' && sz[1] == 0))
{
if ( (!SLASH(path[lstrlen(path)-1])) && ((path[lstrlen(path)-1]) != ':') )
lstrcat(path,CHSEPSTR);
lstrcat(path,sz);
}
}
PSTR FAR PASCAL FileName(PSTR szPath)
{
PSTR sz;
for (sz=szPath; *sz; sz++)
;
for (; sz>=szPath && !SLASH(*sz) && *sz!=':'; sz--)
;
return ++sz;
}
PSTR FAR PASCAL StripPathName(PSTR szPath)
{
PSTR sz;
sz = FileName(szPath);
if (sz > szPath+1 && SLASH(sz[-1]) && sz[-2] != ':')
sz--;
*sz = 0;
return szPath;
}